package com.aierjun.myapplication.utils;

/**
 * Created by Ani_aierJun on 2017/9/6.
 */

import android.app.Activity;
import android.content.res.AssetManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.media.ExifInterface;
import android.os.Environment;
import android.util.Log;

import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;



public class BitmapUtil {
    private static FilePathCallBack filePathCallBacks;

    /**

     * 上传服务器时把图片调用下面方法压缩后 保存到临时文件夹 图片压缩后小于100KB，失真度不明显

     */

    public static Bitmap revitionImageSize(String path) throws IOException {

        BufferedInputStream in = new BufferedInputStream(new FileInputStream(new File(path)));

        BitmapFactory.Options options = new BitmapFactory.Options();

        options.inJustDecodeBounds = true;

        BitmapFactory.decodeStream(in, null, options);

        in.close();

        int i = 0;

        Bitmap bitmap = null;

        while (true) {

            if ((options.outWidth >> i <= 1000) && (options.outHeight >> i <= 1000)) {

                in = new BufferedInputStream(new FileInputStream(new File(path)));

                options.inSampleSize = (int) Math.pow(2.0D, i);

                options.inJustDecodeBounds = false;

                bitmap = BitmapFactory.decodeStream(in, null, options);

                break;

            }

            i += 1;

        }

        return bitmap;

    }





    public static String saveBitmap_Add(Bitmap bm, String folder, String picName) {

        try {

            if (!FileUtils.isFileExist(folder)) {

                FileUtils.createFolders(folder);

            }

            File f = new File(folder, picName + ".JPEG");

            if (f.exists()) {

                f.delete();

            }

            FileOutputStream out = new FileOutputStream(f);

            bm.compress(Bitmap.CompressFormat.JPEG, 90, out);

            out.flush();

            out.close();

            Log.d("Jun","BitmapUtil : " + f.getAbsolutePath() + "已经保存");

            return f.getAbsolutePath();

        } catch (FileNotFoundException e) {

            e.printStackTrace();

            return null;

        } catch (IOException e) {

            e.printStackTrace();

            return null;

        }

    }



    public static String saveBitmap(Bitmap bm, String folder, String picName) {

        try {

            if (!FileUtils.isFileExist(folder)) {

                FileUtils.createFolders(folder);

            }

            File f = new File(folder, picName);

            if (f.exists()) {

                f.delete();

            }

            FileOutputStream out = new FileOutputStream(f);

            Log.d("Jun bitmap 11111111", bm.toString());
            bm.compress(Bitmap.CompressFormat.JPEG, 90, out);

            out.flush();

            out.close();

            Log.d("Jun","BitmapUtil : " + f.getAbsolutePath() + "已经保存");

            return f.getAbsolutePath();

        } catch (FileNotFoundException e) {

            e.printStackTrace();

            return null;

        } catch (IOException e) {

            e.printStackTrace();

            return null;

        }

    }



    public static Bitmap getImageBitmap(String url) {

        URL imgUrl = null;

        Bitmap bitmap = null;

        try {

            imgUrl = new URL(url);

            HttpURLConnection conn = (HttpURLConnection) imgUrl

                    .openConnection();

            conn.setDoInput(true);

            conn.connect();

            InputStream is = conn.getInputStream();

            bitmap = BitmapFactory.decodeStream(is);

            is.close();

        } catch (MalformedURLException e) {

            // TODO Auto-generated catch block

            e.printStackTrace();

        } catch (IOException e) {

            e.printStackTrace();

        }

        return bitmap;

    }



    public Bitmap getDiskBitmap(String pathString) {

        Bitmap bitmap = null;

        try {

            File file = new File(pathString);

            if (file.exists()) {

                bitmap = BitmapFactory.decodeFile(pathString);

            }

        } catch (Exception e) {

            Log.d("Jun","BitmapUtil : GetDiskBitmap error!");

        }



        return bitmap;

    }



    /**

     * @param url

     * @return

     */

    public static Bitmap getLoacalBitmap(String url) {

        try {

            FileInputStream fis = new FileInputStream(url);

            return BitmapFactory.decodeStream(fis);

        } catch (FileNotFoundException e) {

            e.printStackTrace();

            return null;

        }

    }



    /**

     * 从exif信息获取图片旋转角度

     *

     * @param path

     * @return

     */

    public static int readPictureDegree(String path) {

        int degree = 0;

        try {

            ExifInterface exifInterface = new ExifInterface(path);

            int orientation = exifInterface.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);

            switch (orientation) {

                case ExifInterface.ORIENTATION_ROTATE_90:

                    degree = 90;

                    break;

                case ExifInterface.ORIENTATION_ROTATE_180:

                    degree = 180;

                    break;

                case ExifInterface.ORIENTATION_ROTATE_270:

                    degree = 270;

                    break;

            }

        } catch (IOException e) {

            e.printStackTrace();

        }

        return degree;

    }



    /**

     * 对图片进行压缩选择处理

     *

     * @param picPath

     * @return

     */

    public static Bitmap compressRotateBitmap(String picPath) {

        Bitmap bitmap = null;

        int degree = readPictureDegree(picPath);

        if (degree == 90) {

            bitmap = featBitmapToSuitable(picPath, 500, 1.8f);

            bitmap = rotate(bitmap, 90);

        } else {

            bitmap = featBitmapToSuitable(picPath, 500, 1.8f);

        }

        return bitmap;

    }



    /**

     * 转换bitmap为字节数组

     *

     * @param bitmap

     * @return

     */

    public static byte[] bitmapToBytes(Bitmap bitmap) {

        final int size = bitmap.getWidth() * bitmap.getHeight() * 4;

        final ByteArrayOutputStream out = new ByteArrayOutputStream(size);

        bitmap.compress(Bitmap.CompressFormat.JPEG, 100, out);

        byte[] image = out.toByteArray();

        if (out != null) {

            try {

                out.close();

            } catch (IOException e) {

                e.printStackTrace();

            }

        }

        return image;



    }



    /**

     * 获取合适尺寸的图片 图片的长或高中较大的值要 < suitableSize*factor

     *

     * @param path

     * @param suitableSize

     * @return

     */

    public static Bitmap featBitmapToSuitable(String path, int suitableSize,

                                              float factor) {

        Bitmap bitmap = null;

        try {

            BitmapFactory.Options options = new BitmapFactory.Options();

            options.inJustDecodeBounds = true;

            BitmapFactory.decodeFile(path, options);

            options.inJustDecodeBounds = false;

            options.inSampleSize = 1;

            options.inPreferredConfig = Bitmap.Config.RGB_565;

            options.inPurgeable = true;

            options.inInputShareable = true;

            int bitmap_w = options.outWidth;

            int bitmap_h = options.outHeight;

            int max_edge = bitmap_w > bitmap_h ? bitmap_w : bitmap_h;

            while (max_edge / (float) suitableSize > factor) {

                options.inSampleSize <<= 1;

                max_edge >>= 1;

            }

            return BitmapFactory.decodeFile(path, options);

        } catch (Exception e) {

        }

        return bitmap;

    }



    public static Bitmap featBitmap(String path, int width) {

        Bitmap bitmap = null;

        try {

            BitmapFactory.Options options = new BitmapFactory.Options();

            options.inJustDecodeBounds = true;

            BitmapFactory.decodeFile(path, options);

            options.inJustDecodeBounds = false;

            options.inSampleSize = 1;

            options.inPreferredConfig = Bitmap.Config.RGB_565;

            options.inPurgeable = true;

            options.inInputShareable = true;

            int bitmap_w = options.outWidth;

            while (bitmap_w / (float) width > 2) {

                options.inSampleSize <<= 1;

                bitmap_w >>= 1;

            }

            return BitmapFactory.decodeFile(path, options);

        } catch (Exception e) {

        }

        return bitmap;

    }



    public static Bitmap loadBitmap(String path, int maxSideLen) {

        if (null == path) {

            return null;

        }

        BitmapFactory.Options options = new BitmapFactory.Options();

        options.inJustDecodeBounds = true;

        BitmapFactory.decodeFile(path, options);

        options.inJustDecodeBounds = false;

        options.inSampleSize = Math.max(options.outWidth / maxSideLen, options.outHeight / maxSideLen);

        if (options.inSampleSize < 1) {

            options.inSampleSize = 1;

        }

        options.inPreferredConfig = Bitmap.Config.RGB_565;

        try {

            Bitmap bitmap = BitmapFactory.decodeFile(path, options);

            if (bitmap != bitmap) {

                bitmap.recycle();

            }

            return bitmap;

        } catch (OutOfMemoryError e) {

            Log.d("Jun","higo"+ e.toString());

        }

        return null;

    }



    public static Bitmap loadBitmap(String path) {

        if (null == path) {

            return null;

        }

        BitmapFactory.Options options = new BitmapFactory.Options();

        //不对图进行压缩

        options.inSampleSize = 1;

        options.inPreferredConfig = Bitmap.Config.ARGB_8888;

        try {

            Bitmap bitmap = BitmapFactory.decodeFile(path, options);

            return bitmap;

        } catch (OutOfMemoryError e) {

            Log.d("Jun","higo"+e.toString());

        }

        return null;

    }



    public static Bitmap loadFromAssets(Activity activity, String name, int sampleSize, Bitmap.Config config) {

        AssetManager asm = activity.getAssets();

        try {

            InputStream is = asm.open(name);

            BitmapFactory.Options options = new BitmapFactory.Options();

            options.inSampleSize = sampleSize;

            options.inPreferredConfig = config;

            try {

                Bitmap bitmap = BitmapFactory.decodeStream(is);

                is.close();

                return bitmap;

            } catch (OutOfMemoryError e) {

                Log.d("Jun","decode bitmap " + e.toString());

            }

        } catch (IOException e) {

            Log.d("Jun",e.toString());

            e.printStackTrace();

        }

        return null;

    }



    public static Bitmap decodeByteArrayUnthrow(byte[] data, BitmapFactory.Options opts) {

        try {

            return BitmapFactory.decodeByteArray(data, 0, data.length, opts);

        } catch (Throwable e) {

            Log.d("Jun",e.toString());

        }



        return null;

    }



    public static Bitmap rotateAndScale(Bitmap b, int degrees, float maxSideLen) {



        return rotateAndScale(b, degrees, maxSideLen, true);

    }



    // Rotates the bitmap by the specified degree.

    // If a new bitmap is created, the original bitmap is recycled.

    public static Bitmap rotate(Bitmap b, int degrees) {

        if (degrees != 0 && b != null) {

            Matrix m = new Matrix();

            m.setRotate(degrees);

            try {

                Bitmap b2 = Bitmap.createBitmap(b, 0, 0, b.getWidth(), b.getHeight(), m, true);

                if (null != b2 && b != b2) {

                    b.recycle();

                    b = b2;

                }

            } catch (OutOfMemoryError ex) {

                // We have no memory to rotate. Return the original bitmap.

            }

        }

        return b;

    }



    public static Bitmap rotateNotRecycleOriginal(Bitmap b, int degrees) {

        if (degrees != 0 && b != null) {

            Matrix m = new Matrix();

            m.setRotate(degrees);

            try {

                return Bitmap.createBitmap(b, 0, 0, b.getWidth(), b.getHeight(), m, true);

            } catch (OutOfMemoryError ex) {

                // We have no memory to rotate. Return the original bitmap.

            }

        }

        return b;

    }



    public static Bitmap rotateAndScale(Bitmap b, int degrees, float maxSideLen, boolean recycle) {

        if (null == b || degrees == 0 && b.getWidth() <= maxSideLen + 10 && b.getHeight() <= maxSideLen + 10) {

            return b;

        }



        Matrix m = new Matrix();

        if (degrees != 0) {

            m.setRotate(degrees);

        }



        float scale = Math.min(maxSideLen / b.getWidth(), maxSideLen / b.getHeight());

        if (scale < 1) {

            m.postScale(scale, scale);

        }

        Log.d("Jun","degrees: " + degrees + ", scale: " + scale);



        try {

            Bitmap b2 = Bitmap.createBitmap(b, 0, 0, b.getWidth(), b.getHeight(), m, true);

            if (null != b2 && b != b2) {

                if (recycle) {

                    b.recycle();

                }

                b = b2;

            }

        } catch (OutOfMemoryError e) {

        }



        return b;

    }



    public static boolean saveBitmap2file(Bitmap bmp, File file, Bitmap.CompressFormat format, int quality) {

        if (file.isFile())

            file.delete();

        OutputStream stream = null;

        try {

            stream = new FileOutputStream(file);

        } catch (FileNotFoundException e) {

            Log.d("Jun",e.toString());

            return false;

        }



        return bmp.compress(format, quality, stream);

    }

    /*
    * 压缩图片
    */

    public static Bitmap rotateBitmapSize(Bitmap bitmap){
        String imagePath = BitmapUtil.saveBitmap(bitmap, Environment.getExternalStorageDirectory().getAbsolutePath()+"/ImageFolder",System.currentTimeMillis()+".png");
        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        BitmapFactory.decodeFile(imagePath,options);
        int height = options.outHeight;
        int width = options.outWidth;
        int inSampleSize = 2;
        int minLen =Math.min(height,width);
        if (minLen > 100){
            float ratio = (float) minLen/100.0f;
            inSampleSize = (int)ratio;
        }
        options.inJustDecodeBounds = false;
        options.inSampleSize = inSampleSize;
        Bitmap bm = BitmapFactory.decodeFile(imagePath,options);
        Log.d("Jun ", "size: " + bm.getByteCount() + " width: " + bm.getWidth() + " heigth:" + bm.getHeight()); // 输出图像数据
        return bm;
    }

    /*
    *压缩图片
    * 此方法用在子线程中，耗时操作
    */

    public static Bitmap rotateBitmapSize(String urlPath){
        Bitmap b = BitmapUtil.getImageBitmap(urlPath);
        Bitmap bb = BitmapUtil.rotateBitmapSize(b);
        b.recycle();
        return  bb;
    }


    public static Bitmap rotateBitmapSize(Bitmap bitmap ,boolean delFile){
        String imagePathFile = BitmapUtil.saveBitmap(bitmap, Environment.getExternalStorageDirectory().getAbsolutePath()+"/ImageFolder",System.currentTimeMillis()+".png");
        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        BitmapFactory.decodeFile(imagePathFile,options);
        int height = options.outHeight;
        int width = options.outWidth;
        int inSampleSize = 2;
        int minLen =Math.min(height,width);
        if (minLen > 100){
            float ratio = (float) minLen/100.0f;
            inSampleSize = (int)ratio;
        }
        options.inJustDecodeBounds = false;
        options.inSampleSize = inSampleSize;
        Bitmap bm = BitmapFactory.decodeFile(imagePathFile,options);
        Log.d("Jun ", "size: " + bm.getByteCount() + " width: " + bm.getWidth() + " heigth:" + bm.getHeight()); // 输出图像数据
        if (delFile){
            FileUtils.deleteFile(imagePathFile);
        } else{
            if (filePathCallBacks!=null)
                filePathCallBacks.getPathFile(imagePathFile);
        }
        return bm;
    }

    public static Bitmap rotateBitmapSize(String urlPath , boolean delFile){
        Bitmap b = BitmapUtil.getImageBitmap(urlPath);
        Bitmap bb = BitmapUtil.rotateBitmapSize(b,delFile);
        b.recycle();
        return  bb;
    }

    public interface FilePathCallBack{
        void getPathFile(String path);
    }

    /*
    * 只能当设置delFile参数为false时才会有返回
    * 请在压缩之前设置接口
    */

    public static void setFilePathCallBack(FilePathCallBack filePathCallBack){
        filePathCallBacks = filePathCallBack;
    }


    public static Bitmap rotateBitmapSize(Bitmap bitmap ,boolean delFile ,FilePathCallBack filePathCallBack){
        String imagePathFile = BitmapUtil.saveBitmap(bitmap, Environment.getExternalStorageDirectory().getAbsolutePath()+"/ImageFolder",System.currentTimeMillis()+".png");
        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        BitmapFactory.decodeFile(imagePathFile,options);
        int height = options.outHeight;
        int width = options.outWidth;
        int inSampleSize = 2;
        int minLen =Math.min(height,width);
        if (minLen > 100){
            float ratio = (float) minLen/100.0f;
            inSampleSize = (int)ratio;
        }
        options.inJustDecodeBounds = false;
        options.inSampleSize = inSampleSize;
        Bitmap bm = BitmapFactory.decodeFile(imagePathFile,options);
        Log.d("Jun ", "size: " + bm.getByteCount() + " width: " + bm.getWidth() + " heigth:" + bm.getHeight()); // 输出图像数据
        if (delFile){
            FileUtils.deleteFile(imagePathFile);
        } else{
            if (filePathCallBack!=null)
                filePathCallBack.getPathFile(imagePathFile);
        }
        return bm;
    }

    public static Bitmap rotateBitmapSize(String urlPath , boolean delFile ,FilePathCallBack filePathCallBack){
        Bitmap b = BitmapUtil.getImageBitmap(urlPath);
        Bitmap bb = BitmapUtil.rotateBitmapSize(b,delFile,filePathCallBack);
        b.recycle();
        return  bb;
    }
}



